package com.chencl.cipher.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.chencl.cipher.config.log.OperationLogDetail;
import com.chencl.cipher.config.log.OperationType;
import com.chencl.cipher.config.log.OperationUnit;
import com.chencl.cipher.service.SecretKeyService;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.chencl.cipher.annotation.Decrypt;
import com.chencl.cipher.annotation.Encrypt;
import com.chencl.cipher.cache.SecretUserCache;
import com.chencl.cipher.config.SecretKeyConfig;
import com.chencl.cipher.dto.RequestBodyDTO;
import com.chencl.cipher.dto.ResponseBodyDTO;
import com.chencl.cipher.dto.SecretDataDTO;
import com.chencl.cipher.entity.SecretKeyEntity;
import com.chencl.cipher.util.AESUtils;
import com.chencl.cipher.util.MD5Util;
import com.chencl.cipher.util.RSAUtils;
import com.chencl.cipher.util.RandomUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/test")
@Validated
public class TestController {

	@Autowired
	SecretKeyConfig secretKeyConfig;
	@Autowired
	private SecretKeyService secretKeyService;

//	@PostConstruct
	@PostMapping(value = "/init")
	public void init(){
		log.info("初始化开始-------------------");

		Map<String,String> resKey1 = RSAUtils.getRsaKey();
		Map<String,String> resKey2 = RSAUtils.getRsaKey();

		SecretKeyEntity entity1 = SecretKeyEntity.builder().appid("123456").publicKey(resKey1.get("publiceKey")).privateKey(resKey1.get("privateKey")).build();
		SecretKeyEntity entity2 = SecretKeyEntity.builder().appid(secretKeyConfig.getAppid()).publicKey(resKey2.get("publiceKey")).privateKey(resKey2.get("privateKey")).build();
		secretKeyService.insertSecretKey(entity1);
		secretKeyService.insertSecretKey(entity2);
		log.info("初始化结束-------------------");
	}

	@Decrypt
	@Encrypt
	@PostMapping(value = "/ask")
	@OperationLogDetail(detail = "测试接口appid:[{{appid}}]",level = 1,operationUnit = OperationUnit.USER,operationType = OperationType.SELECT)
    public ResponseBodyDTO ask(@RequestBody RequestBodyDTO data){
    	log.info("测试接口,请求参数:[{}]",data);
    	Map<String,Object> retMap = new HashMap<>();
    	retMap.put("test1","test123");
        return ResponseBodyDTO.buildSuccess(retMap);
    }

	@Decrypt
	@PostMapping(value = "/ask2")
    public ResponseBodyDTO ask2(@RequestBody RequestBodyDTO data){
    	log.info("测试接口,请求参数:[{}]",data);
    	Map<String,Object> retMap = new HashMap<>();
    	retMap.put("test1","test123");
        return ResponseBodyDTO.buildSuccess(retMap);
    }

	@PostMapping(value = "/ask3")
    public ResponseBodyDTO ask3(@RequestBody RequestBodyDTO data){
    	log.info("测试接口,请求参数:[{}]",data);
    	Map<String,Object> retMap = new HashMap<>();
    	retMap.put("test1","test123");
        return ResponseBodyDTO.buildSuccess(retMap);
    }

	@PostMapping(value = "/get")
    public ResponseBodyDTO get(){
		String content = "";
		String sign = "";
		String random_key = "";
		try {
			List<Map<String,Object>> list = new ArrayList<>();
			Map<String,Object> map1 = new HashMap<>();
			map1.put("test3", "789");
			list.add(map1);
			RequestBodyDTO entity = new RequestBodyDTO();
			entity.setData(list);
			String data = JSONObject.toJSONString(entity);

			SecretKeyEntity sender = secretKeyService.getSecretKeyByAppid("123456");
			SecretKeyEntity home = secretKeyService.getSecretKeyByAppid(secretKeyConfig.getAppid());

			String aesKey = RandomUtils.getUUIDRandomTrim();
			content = AESUtils.encrypt(data, aesKey);
			String content_digest = MD5Util.MD5Encode(data);
			sign = RSAUtils.encryptByPrivateKey(content_digest.getBytes("UTF-8"),sender.getPrivateKey());
			random_key = RSAUtils.encryptByPublicKey(aesKey.getBytes("UTF-8"),home.getPublicKey());

			Map<String,Object> retMap = new HashMap<>();
			retMap.put("appid","123456");
	    	retMap.put("content",URLEncoder.encode(content,"utf-8"));
	    	retMap.put("sign",URLEncoder.encode(sign,"utf-8"));
	    	retMap.put("random_key",URLEncoder.encode(random_key,"utf-8"));
	        return ResponseBodyDTO.buildSuccess(retMap);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		 return ResponseBodyDTO.buildSuccess("");
    }

	/**
	 * 解密测试
	 * @param entity
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@PostMapping(value = "/decode")
    public ResponseBodyDTO decode(@RequestBody SecretDataDTO entity) throws UnsupportedEncodingException{
		String appid = "100000";
		String content = URLDecoder.decode(entity.getContent(),"utf-8");
		String sign = URLDecoder.decode(entity.getSign(),"utf-8");
		String random_key = URLDecoder.decode(entity.getRandom_key(),"utf-8");

		SecretKeyEntity sender = secretKeyService.getSecretKeyByAppid(appid);
		SecretKeyEntity home = secretKeyService.getSecretKeyByAppid("100001");

		String decode_random_key = "";
		String decode_content = "";
		String decode_sign = "";

		try {
			decode_random_key = RSAUtils.decryptByPrivateKey(Base64.decodeBase64(random_key.getBytes("UTF-8")),home.getPrivateKey());
		    decode_content = AESUtils.decrypt(content, decode_random_key);
		    decode_sign = RSAUtils.decryptByPublicKey(Base64.decodeBase64(sign.getBytes("UTF-8")),sender.getPublicKey());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		boolean isVerifi = MD5Util.MD5Encode(decode_content).equals(decode_sign);

		Map<String,Object> retMap = new HashMap<>();
		retMap.put("isVerifi",isVerifi);
		retMap.put("decode_content_digest",MD5Util.MD5Encode(decode_content));
		retMap.put("decode_random_key",decode_random_key);
		retMap.put("decode_content",decode_content);
		retMap.put("decode_sign",decode_sign);
		return ResponseBodyDTO.buildSuccess(retMap);
	}

	/**
	 * 测试生成请求密钥参数
	 * @param args
	 */
	public static void main(String[] args) {
		String content = "";
		String sign = "";
		String random_key = "";
		try {
			List<Map<String,Object>> list = new ArrayList<>();
			Map<String,Object> map1 = new HashMap<>();
			map1.put("param1","param1");
			map1.put("param2","param2");
			list.add(map1);
			RequestBodyDTO entity = new RequestBodyDTO();
			entity.setAppid("10001");
			entity.setData(list);
			String data = JSONObject.toJSONString(entity);
			String aesKey = RandomUtils.getUUIDRandomTrim();
			content = AESUtils.encrypt(data, aesKey);
			String content_digest = MD5Util.MD5Encode(data);
			sign = RSAUtils.encryptByPrivateKey(content_digest.getBytes("UTF-8"),"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAImAGndQqs6B+6qLvD94N5r97ygE54ihq17XUaxlZ8iWsI/q/k0D67nqZMojMvOJBPYAdIEir0myih2DCKroZJfrKgGCbdIlNws7tQQsv8frbj7xxZpsw4eSaNRL1wzBfygc2qk0HkrezfJTWhQrdTkr/wKkvDO8bzFltLQzu1sPAgMBAAECgYB+1XkUWIfGh+ZCsjUKgvUf9l82FhgRU7gFey7ujHfIcyAZEVZUamp2C32/a+qi9OBrn43YVMtGevemM2m6ZTXsBcXXqkSuPNDByEvPhzZVzYEGwE26jEYAKXuM0wfEKCLm2OXfsWmUFf8SV/ikxKRH7oZJQFQJJAt81erF94W7QQJBAMnVGWkmV6LCqnijhN65nEFYtVXqyUtG9FlqfQvhPiKw/uGXgU2Kbo+nIPI273w3+yvYlcbWZFAccmfECXiGZO8CQQCuZxJVyqIk7ESjn4vv0L/0ovvVhVLDZdmRPMAdiKpgQR/nP0Y9trfuQ/A94Rd1V581dbIJtWjxdIOXFdOs36vhAkBB0M7PfiRXu/kRC+mZI5ezq3S+hqiLdqDZw6LxS8sSTvtenyQYIAs7pvlUYtuney3Zt2/n/iOKCCy6b6/S8KhbAkB3/usapEVT6kx/2DLMWnD4vXtQul7rmpRL3eTBbVrsx2JQFbUamTGMeqo9qTYewp8EhWpuS6ddGrG/roDqHSuBAkEAsvH0iId6pRs/5T1mOJJ2tkwxT9J1Xa45FXnr+6arndmGY3Ze1ZH4XdUVeeWYA34hqD1+qaLbl8sXT7QSJzJUZA==");
			random_key = RSAUtils.encryptByPublicKey(aesKey.getBytes("UTF-8"),"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgaNFN2JltcKpBQowdTAIu7cnXyL/nesZfjNNEMWDXHoFt53S2ETIfjB5GYgHk1dukrBgCOPnu8fV9c120Cg0SBvohwN5u926ULAw9mcLtyy5eKZLIhMq9LSPRFYHgt9dihrwpKqC53qrshucQQvvZSVYFNNEden1NQRuLUXf+kwIDAQAB");
			String a = URLEncoder.encode(content,"utf-8");
			String b = URLEncoder.encode(sign,"utf-8");
			String c = URLEncoder.encode(random_key,"utf-8");
			System.out.println("appid:100001");
			System.out.println("content:"+a);
			System.out.println("sign:"+b);
			System.out.println("random_key:"+c);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
